package xyz.shuixiangyu.core;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

import xyz.shuixiangyu.movie.Movie;

public class FilmDirectoryWorker {
	private final int maxOfFilmsPerPage = 7;
	private final String css = System.getProperty("user.dir") + "/lib/main.css";
	private final String icon = System.getProperty("user.dir")
			+ "/lib/film.ico";
	private final String destination;
	private boolean hasCssAndIcon;
	private HtmlProducer producer;

	public FilmDirectoryWorker(String des) throws IOException {
		destination = des;
		hasCssAndIcon = hasFile(new File(css)) && hasFile(new File(icon));
		producer = new HtmlProducer();
	}

	public void add(List<Movie> movies) throws IOException {
		if (!hasCssAndIcon) {
			copy(css, destination);
			copy(icon, destination);
			hasCssAndIcon = true;
		}
		List<Movie> alreadyHas=new LinkedList<>();
		for (Movie movie : movies) {
			if (hasFile(new File(movie.getPhoto()))) {
				alreadyHas.add(movie);		
			}else{
				copy(movie.getPhoto(), destination);						
			}
		}
		movies.removeAll(alreadyHas);
		if(movies.size()==0) return;
		int page = getLastPageNumber();
		if (getLastPageNumber() == 0) {
			createNewPages(movies,1);
		} else {
			int numOfLastPage = producer.numOfMovies(destination+"/"+page + ".html");
			if (numOfLastPage < maxOfFilmsPerPage) {
				int less=maxOfFilmsPerPage-numOfLastPage;
				if(movies.size()>less){
					Movie[] ms=new Movie[less];
					for(int i=0;i<less;i++){
						ms[i]=movies.get(i);
					}
					writeFile(new File(destination+"/"+page+".html"),producer.addMovie(ms, destination+"/"+page+".html"));
					movies.removeAll(Arrays.asList(ms));
					createNewPages(movies,page+1);
				}else{
					Movie[] ms=new Movie[movies.size()];
					for(int i=0;i<ms.length;i++){
						ms[i]=movies.get(i);
					}
					writeFile(new File(destination+"/"+page+".html"),producer.addMovie(ms, destination+"/"+page+".html"));
				}
			} else {
				createNewPages(movies,page+1);
			}
		}
	}

	private void createNewPages(List<Movie> movies, int pageStart) throws FileNotFoundException {
		Movie[] ms=new Movie[maxOfFilmsPerPage];
		for(int i=0;i<movies.size();i++){
			int j=0;
			while((j=i%maxOfFilmsPerPage)<maxOfFilmsPerPage&&i<movies.size()){
				ms[j]=movies.get(i);	
				if(j==maxOfFilmsPerPage-1){
					break;
				}
				i++;
			}
			try {
				newFile((pageStart++)+".html",producer.produce(ms, (pageStart)+".html"));
				for(int k=0;k<ms.length;k++){
					ms[k]=null;
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		String newLatPage=producer.updateLastPage(destination+"/"+(pageStart-1)+".html");
		try {
			writeFile(new File(destination+"/"+(pageStart-1)+".html"),newLatPage);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private boolean hasFile(File file) {
		File[] files = new File(destination).listFiles();
		boolean has = false;
		for (File f : files) {
			if (f.getName().equals(file.getName())) {
				has = true;
				break;
			}
		}

		return has;
	}

	private void copy(String src, String des) throws IOException {
		if (new File(des).isDirectory()) {
			int byteread = 0;
			FileInputStream inStream = new FileInputStream(src); // 读入原文件
			File newFile = new File(des + "/" + new File(src).getName());
			newFile.createNewFile();
			FileOutputStream fs = new FileOutputStream(newFile);
			byte[] buffer = new byte[1024];
			while ((byteread = inStream.read(buffer)) != -1) {
				fs.write(buffer, 0, byteread);
			}
			inStream.close();
			fs.close();
		}else{
			System.err.println(des+" is not directory");
		}
	}

	private int getLastPageNumber() {
		File[] files = new File(destination).listFiles(s -> s.getName()
				.endsWith("html"));
		if (files.length == 0) {
			return 0;
		}
		int[] pages = new int[files.length];
		for (int i = 0; i < pages.length; i++) {
			try{
				pages[i] = Integer.parseInt(files[i].getName().substring(0,
						files[i].getName().indexOf(".html")));	
			}catch(NumberFormatException e){
				pages[i]=0;
			}
		}
		return max(pages);
	}

	private int max(int[] arr) {
		int max = arr[0];
		for (int i = 1; i < arr.length; i++) {
			if (arr[i] > max) {
				max = arr[i];
			}
		}
		return max;
	}

	private void newFile(String fileName, String content) throws IOException {
		File file=new File(destination+"/"+fileName);
		if(!file.exists()){
			file.createNewFile();
		}
		writeFile(file,content);
	}
	
	private void writeFile(File file, String content) throws IOException{
		BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file),"utf-8"));
		bw.write(content);
		bw.close();
	}
}
